package pl.iachoo.ctl.tabory.ui.editors.vagons.composites;

import java.util.List;

import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.forms.SectionPart;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.Section;

import pl.iachoo.ctl.tabory.dao.hibernate.vo.CompositionVO;
import pl.iachoo.ctl.tabory.dao.hibernate.vo.VagonVO;
import pl.iachoo.ctl.tabory.ui.editors.vagons.VagonSelection;
import pl.iachoo.ctl.tabory.ui.properties.Messages;
import pl.iachoo.ctl.tabory.ui.selection.ISelectionListener;
import pl.iachoo.ctl.tabory.ui.selection.ISelectionProvider;

public class VagonTableSectionPart extends SectionPart implements
		ISelectionProvider<VagonSelection> {

	private String sectionName;

	private ToolItem toolItemNew;
	private ToolItem toolItemEdit;
	private ToolItem toolItemDelete;
	private Table table;
	private TableViewer tableViewer;

	private VagonSelection selection;
	private ISelectionListener<VagonSelection> selectionListener;

	private final boolean toolBarVisible;
	private final boolean filterVisible;
	private Section filterSection;
	private Composite composite;
	private Text filterVagonName;
	private Text filterCompositionName;
	private VagonNameFilter vagonNameFilter;

	/**
	 * Create the SectionPart.
	 * 
	 * @param parent
	 * @param toolkit
	 * @param style
	 */
	public VagonTableSectionPart(Composite parent, FormToolkit toolkit,
			String sectionName, boolean toolBarVisible, boolean filterVisible) {
		super(parent, toolkit, Section.TITLE_BAR);
		this.sectionName = sectionName;
		this.toolBarVisible = toolBarVisible;
		this.filterVisible = filterVisible;
		createClient(getSection(), toolkit);
		refreshActionStatus();
		initActions();
	}

	/**
	 * Fill the section.
	 */
	private void createClient(Section section, FormToolkit toolkit) {
		section.setText(sectionName);
		Composite container = toolkit.createComposite(section);

		ToolBar toolBar = new ToolBar(section, SWT.FLAT | SWT.HORIZONTAL);
		toolItemNew = new ToolItem(toolBar, SWT.FLAT);
		toolItemNew.setImage(PlatformUI.getWorkbench().getSharedImages()
				.getImage(ISharedImages.IMG_TOOL_NEW_WIZARD));
		toolItemNew.setToolTipText(Messages.getString("common.addnew"));
		toolItemEdit = new ToolItem(toolBar, SWT.PUSH);
		toolItemEdit.setImage(PlatformUI.getWorkbench().getSharedImages()
				.getImage(ISharedImages.IMG_TOOL_COPY));
		toolItemEdit.setToolTipText(Messages.getString("common.edit"));
		toolItemDelete = new ToolItem(toolBar, SWT.PUSH);
		toolItemDelete.setImage(PlatformUI.getWorkbench().getSharedImages()
				.getImage(ISharedImages.IMG_TOOL_DELETE));
		toolItemDelete.setToolTipText(Messages.getString("common.delete"));
		toolkit.paintBordersFor(toolBar);
		section.setTextClient(toolBar);

		toolBar.setVisible(toolBarVisible);

		section.setClient(container);
		container.setLayout(new GridLayout(1, false));

		tableViewer = new TableViewer(container, SWT.BORDER
				| SWT.FULL_SELECTION);
		tableViewer.setSorter(new Sorter());
		table = tableViewer.getTable();
		table.setHeaderVisible(true);
		table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
		toolkit.paintBordersFor(table);

		TableViewerColumn tableViewerColumn = new TableViewerColumn(
				tableViewer, SWT.NONE);
		TableColumn tblclmnNewColumn = tableViewerColumn.getColumn();
		tblclmnNewColumn.setWidth(100);
		tblclmnNewColumn
				.setText(Messages.getString("vagons.editor.table.col0"));

		filterSection = toolkit.createSection(container, Section.TWISTIE
				| Section.TITLE_BAR);
		filterSection.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false,
				false, 1, 1));
		toolkit.paintBordersFor(filterSection);
		filterSection.setText(Messages.getString("common.filter"));
		filterSection.setVisible(filterVisible);

		composite = toolkit.createComposite(filterSection, SWT.NONE);
		toolkit.paintBordersFor(composite);
		filterSection.setClient(composite);
		composite.setLayout(new GridLayout(2, false));

		toolkit.createLabel(composite,
				Messages.getString("vagons.editor.filter.vagonname"), SWT.NONE);

		filterVagonName = new Text(composite, SWT.NONE);
		filterVagonName.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true,
				false, 1, 1));
		toolkit.adapt(filterVagonName, true, true);

		toolkit.createLabel(composite,
				Messages.getString("vagons.editor.filter.compositionname"),
				SWT.NONE);

		filterCompositionName = new Text(composite, SWT.NONE);
		filterCompositionName.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER,
				true, false, 1, 1));
		toolkit.adapt(filterCompositionName, true, true);

		tableViewer.setContentProvider(new ContentProvider());
		tableViewer.setLabelProvider(new TableLabelProvider());

		// vagonNameFilter = new VagonNameFilter();
		// tableViewer.addFilter(vagonNameFilter);
	}

	private void initActions() {
		toolItemNew.addSelectionListener(new SelectionAdapter() {

			@Override
			public void widgetSelected(SelectionEvent e) {
				performNewItemAction(e);
			}

		});

		toolItemEdit.addSelectionListener(new SelectionAdapter() {

			@Override
			public void widgetSelected(SelectionEvent e) {
				performEditItemAction(e);
			}

		});

		toolItemDelete.addSelectionListener(new SelectionAdapter() {

			@Override
			public void widgetSelected(SelectionEvent e) {
				performDeleteItemAction(e);
			}

		});

		tableViewer
				.addSelectionChangedListener(new ISelectionChangedListener() {

					@Override
					public void selectionChanged(SelectionChangedEvent event) {
						performTableSelectionChange(event);
					}
				});

		filterVagonName.addSelectionListener(new SelectionAdapter() {

			@Override
			public void widgetSelected(SelectionEvent e) {

			}

		});
	}

	protected void performDeleteItemAction(SelectionEvent e) {
		// TODO Auto-generated method stub

	}

	protected void performEditItemAction(SelectionEvent e) {
		// TODO Auto-generated method stub

	}

	protected void performNewItemAction(SelectionEvent e) {
		selection.setEditing(false);
		selection.setNew(true);
		selection.setSelectedVagon(new VagonVO());
		selectionListener.selectionChanged(selection);
		setEnabled(false);
	}

	public void setEnabled(boolean isEnabled) {
		table.setEnabled(isEnabled);
		toolItemDelete.setEnabled(isEnabled);
		toolItemEdit.setEnabled(isEnabled);
		toolItemNew.setEnabled(isEnabled);
		refreshActionStatus();
	}

	protected void performTableSelectionChange(SelectionChangedEvent event) {
		VagonVO selectedVagon = (VagonVO) ((StructuredSelection) tableViewer
				.getSelection()).getFirstElement();
		selection.setSelectedVagon(selectedVagon);
		selectionListener.selectionChanged(selection);
		refreshActionStatus();
		setEnabled(!selection.isEditing());
	}

	private void refreshActionStatus() {
		if (selection == null
				|| (selection != null && selection.getSelectedVagon() == null)) {
			toolItemDelete.setEnabled(false);
			toolItemEdit.setEnabled(false);
			toolItemNew.setEnabled(true);
		} else {
			toolItemDelete.setEnabled(true);
			toolItemEdit.setEnabled(true);
			toolItemNew.setEnabled(true);
		}
	}

	@Override
	public VagonSelection getSelection() {
		return selection;
	}

	@Override
	public void setSelection(VagonSelection selection) {
		this.selection = selection;
		tableViewer.setInput(selection.getListVagons());
		table.setSelection(selection.getListVagons().indexOf(
				selection.getSelectedVagon()));
		setEnabled(!selection.isEditing());
	}

	@Override
	public void addSelectionListener(ISelectionListener<VagonSelection> listner) {
		selectionListener = listner;
	}

	@Override
	public void removeSelectionListener(
			ISelectionListener<VagonSelection> listner) {
		selectionListener = null;
	}

	private static class Sorter extends ViewerSorter {
		public int compare(Viewer viewer, Object e1, Object e2) {
			VagonVO vagon1 = (VagonVO) e1;
			VagonVO vagon2 = (VagonVO) e2;
			return vagon1.getInternalId().compareTo(vagon2.getInternalId());
		}
	}

	private class TableLabelProvider extends LabelProvider implements
			ITableLabelProvider {

		public Image getColumnImage(Object element, int columnIndex) {
			return null;
		}

		public String getColumnText(Object element, int columnIndex) {
			VagonVO vagon = (VagonVO) element;
			switch (columnIndex) {
			case 0:
				return vagon.getInternalId();
			case 1:
				CompositionVO compositionVO = vagon.getCompositionVO();
				if (compositionVO != null) {
					return compositionVO.getInternalId();
				} else {
					return "-";
				}
			default:
				return "--";
			}
		}
	}

	@SuppressWarnings("unchecked")
	private static class ContentProvider implements IStructuredContentProvider {
		public Object[] getElements(Object inputElement) {
			List<VagonVO> list = (List<VagonVO>) inputElement;
			return list.toArray();
		}

		public void dispose() {
		}

		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
		}
	}

	private class VagonNameFilter extends ViewerFilter {

		@Override
		public boolean select(Viewer viewer, Object parentElement,
				Object element) {
			return false;
		}

	}

}
